﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using System.Collections.ObjectModel;
using SQLServerHealthCheck.Model;
using SQLServerOptimizer.PL.WPF;
using SQLServerHealthCheck.SQLServer;
using System.Data.SqlClient;
using System.ComponentModel;
using System.Threading;
using AG.Utilities;


namespace SQLServerOptimizer.PL.WPF
{
    public delegate void RunDatabaseSetup(String sqlServerInstance);
    public delegate void ProgressBarUpdateEvent(String sqlServerInstance, String error);
    public delegate void ProccesDatabaseSetupCompleted();


    public class DatabaseInstallWorker : AsyncUtils.AsyncOperation
    {
        public event ProgressBarUpdateEvent ProgressUpdate;
        public event ProccesDatabaseSetupCompleted ProccessCompleted;
        public int countEventsCalls = 0;

        private string sqlServerInstance;
        public DatabaseInstallWorker(DispatcherObject target, String SQLServerINstance)
            : base(target)
        {
            sqlServerInstance = SQLServerINstance;

        }

        public void Fail()
        {
            lock (this)
            {
                _fail = true;
            }
        }
        private bool _fail;

        protected override void DoWork()
        {
            _fail = false;

            try
            {
                if (!CancelRequested)
                {
                    RunDatabaseSetup runDatabaseSetup = new RunDatabaseSetup(SetupDatabase);
                    runDatabaseSetup.BeginInvoke(sqlServerInstance, null, null);
                }
                if (_fail)
                {
                    throw new Exception();
                }


                if (CancelRequested)
                {
                    AcknowledgeCancel();
                }
            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }

        }
        private void SetupDatabase(String sqlServerInstance)
        {
            try
            {
                DatabaseInstaller.Install(sqlServerInstance);
                countEventsCalls++;
                bool success = false;

                success = CheckDatabaseExists(sqlServerInstance, "SQLServerOptimizer");
                countEventsCalls++;

                if (success)
                {
                    FireProccessCompletedEvent();
                }
                else
                {

                    FireProgressUpdateEvent(sqlServerInstance, "There was an error creating the database.");
                }

            }
            catch (Exception ex)
            {
                Logger.Error(ex);
            }
        }
        public bool CheckDatabaseExists(string server, string database)
        {

            string connString = "Data Source=" + server + ";Initial Catalog=master;Integrated Security=True;";

            string cmdText = "select * from master.dbo.sysdatabases where name=\'" + database + "\'";

            bool bRet = false;
            try
            {
                using (SqlConnection sqlConnection = new SqlConnection(connString))
                {


                    sqlConnection.Open();

                    using (SqlCommand sqlCmd = new SqlCommand(cmdText, sqlConnection))
                    {

                        SqlDataReader reader = sqlCmd.ExecuteReader();

                        bRet = reader.HasRows;

                        reader.Close();

                    }

                    sqlConnection.Close();

                }


            }
            catch (Exception ex)
            {
                FireProgressUpdateEvent(sqlServerInstance, "There was an error creating the database");
                Logger.Error(ex);
            }

            return bRet;
        }


        private void FireProgressUpdateEvent(String sqlServerInstance, String status)
        {
            Object[] param = new Object[] { sqlServerInstance, status };

            FireAsync(ProgressUpdate, param);
        }
        private void FireProccessCompletedEvent()
        {
            if (countEventsCalls == 2)
            {

                FireAsync(ProccessCompleted);
                countEventsCalls = 0;
            }

        }

    }



}


